/**
 * README
 * 
 * Modificacion de la biblioteca jWave disponible en http://code.google.com/p/jwave/
 * Convertidos los tipos de datos a float para agilizar el tratamiendo de grandes arrays de datos
 * como son los que se tratan en analisis genomicos.
 * Los autores originales de las funciones y del código de la biblioteca cuando fue seleccionada en
 * Abril de 2012 eran:
 *        Christian Scheiblich
 *        Thomas Leduc
 *        sashi
 *        Pol Kennel
 *        Thomas Haider
 *        
 * Por supuesto, todo el merito, honores y demas menciones sobre esta adaptacion les corresponden a ellos
 * y nada mas que a ellos.
 * 
 * 
 * This is a modified version of jWave, available in http://code.google.com/p/jwave/
 * It has been replace the double datatype with float for performance reasons in very big arrays used in
 * bioinformatics like genomic analysis.
 * Original authors of functions and the library when it has been selected in 2012's April were:
 *        Christian Scheiblich
 *        Thomas Leduc
 *        sashi
 *        Pol Kennel
 *        Thomas Haider
 *        
 * Of course, all the merits and mentions about this adaptation have corresponded to them.
 * 
 */

package ev.maths.handlers.wavelets;

/**
 * Wavelet de Alfred Haar Ortogonal.
 * 
 * @date 01.08.2012
 * @author Enrique Vázquez de Luis
 */
public class Haar02Orthogonal extends Wavelet {

  /**
   * Constructor que establece los coeficientes y las escalas.
   * 
   * @date 01.08.2012
   * @author Enrique Vázquez de Luis
   */
  public Haar02Orthogonal( ) {

    _waveLength = 2;

    _coeffs = new float[ _waveLength ]; 

    
    _coeffs[ 0 ] = (float) 1.; // w0 
    _coeffs[ 1 ] = (float) -1.; //  w1

    _scales = new float[ _waveLength ]; 

    
    _scales[ 0 ] = -_coeffs[ 1 ]; // -w1 
    _scales[ 1 ] = _coeffs[ 0 ]; // w0
  } // Haar02

  /**
   * Transformada utilizando la wavelet de Haar. El arrTime que mantiene los coeficientes
   * en el dominio del tiempo debe tener una potencia positiva de 2 como tamaño.
   * 
   * @date 01.08.2012
   * @author Enrique Vázquez de Luis
   * @see ev.math.handlers.wavelets.Wavelet#forward(double[])
   */
  @Override
  public float[ ] forward( float[ ] arrTime ) {

    float[ ] arrHilb = new float[ arrTime.length ];

    int k = 0;
    int h = arrTime.length >> 1;

    for( int i = 0; i < h; i++ ) {

      for( int j = 0; j < _waveLength; j++ ) {

        k = ( i << 1 ) + j;
        if( k >= arrTime.length )
          k -= arrTime.length;

        arrHilb[ i ] += arrTime[ k ] * _scales[ j ]; 
        arrHilb[ i + h ] += arrTime[ k ] * _coeffs[ j ]; 

        // por cada suma se añade "energía" de acuerdo a la wavelet ortogonal

      } // wavelet

    } // h

    return arrHilb;
  } // forward

  /**
   * La transformada inversa de la wavelet de Haar. El arrHil que mantiene los coeficientes
   * en el dominio de Hilbert debe tener un tamaño potencia positiva de 2.
   * Solo en el caso de la inversa de la transformada ortogonal tenemos un factor
   * de 0.5 que reduce la "energia" añadida en el espacio de Hilbert.
   * 
   * @date 01.08.2012
   * @author Enrique Vázquez de Luis
   * @see ev.math.handlers.wavelets.Wavelet#reverse(double[])
   */
  @Override
  public float[ ] reverse( float[ ] arrHilb ) {

    float[ ] arrTime = new float[ arrHilb.length ];

    int k = 0;
    int h = arrHilb.length >> 1;
    for( int i = 0; i < h; i++ ) {

      for( int j = 0; j < _waveLength; j++ ) {

        k = ( i << 1 ) + j;
        if( k >= arrHilb.length )
          k -= arrHilb.length;

        arrTime[ k ] += ( arrHilb[ i ] * _scales[ j ] + arrHilb[ i + h ]
            * _coeffs[ j ] );

        
        arrTime[ k ] *= .5; 

      } // wavelet

    } //  h

    return arrTime;
  } // reverse
  
} // class
